package main

import (
	"bufio"
	"fmt"
	"io"
	"net"
	"os"
	"strconv"
	"strings"
)

// 上传文件
func upload(conn net.Conn, params []string) {
	// 上传文件
	fileName := params[0]
	fileSize, _ := strconv.Atoi(params[1])
	// 打开文件
	file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		fmt.Println("打开文件失败!", err)
	}
	var buf = make([]byte, 1024)
	var curSize = 0 // 当前已读字节数
	for curSize < fileSize {
		n, _ := conn.Read(buf)
		// 写入文件
		file.Write(buf[:n])
		curSize += n
	}
	fmt.Println("文件保存成功!")
	defer file.Close()
}

// 下载文件
func download(conn net.Conn, params []string) {
	// 打开文件
	fileName := params[0]
	fileInfo, _ := os.Stat(fileName)
	fileSize := fileInfo.Size()
	file, err := os.Open(fileName)
	if err != nil {
		fmt.Println("打开文件失败!", err)
	}
	defer file.Close()
	conn.Write([]byte(strconv.FormatInt(fileSize, 10)))
	reader := bufio.NewReader(file)
	for {
		bytes, err := reader.ReadBytes('\n')
		// 传输给客户端
		conn.Write(bytes)
		if err == io.EOF {
			// 读取结束
			break
		}
	}
	fmt.Println("文件传输完毕!")
}

/*
文件上传下载案例：服务端代码
*/
func main() {
	// 创建tcp监听
	sock, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		fmt.Println("服务器监听失败!", err)
	}
	defer sock.Close()
	for {
		// 等待客户端建立连接
		fmt.Println("服务器等待连接中...")
		conn, _ := sock.Accept()
		defer conn.Close()
		fmt.Println("服务器接收到客户端连接...")
		// 打招呼
		conn.Write([]byte("欢迎来到米饭文件中心..."))
		// 等待客户端输入命令
		var byteArr = make([]byte, 1024)
		n, _ := conn.Read(byteArr)
		fmt.Println("接收到输入:", string(byteArr[:n]))
		var commandSlice = strings.Split(string(byteArr[:n]), " ")
		var op = commandSlice[0]
		var params = commandSlice[1:]
		switch op {
		case "put":
			// 上传文件
			upload(conn, params)
		case "get":
			// 下载文件
			download(conn, params)
		}
		fmt.Println("服务器断开与客户端连接...")
	}
}
